題目除了基本 Gallery 介面樣式以外,還有點擊後的介面
上面的圖是題目,而我們要做出幾乎一樣的樣子,題目中還有附上出題官方的CodePen,也有附上給我們解題用的template,當我們真的不會的時候,還是可以參考他們的寫法,所以沒有想像中困難。
我做好的此題CSS Challeage解答
那麼我們就開始吧。
這個題目要求我們製作一個 User Gallery
<div class="frame">
<div class="gallery">
<div class="pic pic-1"><img src="https://100dayscss.com/codepen/13-1.jpg" /></div>
<div class="pic pic-2"><img src="https://100dayscss.com/codepen/13-2.jpg" /></div>
<div class="pic pic-3"><img src="https://100dayscss.com/codepen/13-3.jpg" /></div>
<div class="pic pic-4"><img src="https://100dayscss.com/codepen/13-4.jpg" /></div>
</div>
</div>
在 .frame
內分成兩個主要的區塊,我們先做第一區的 gallery
。
這邊雖然看起來好像可以用變數來寫四個 div
,但我考慮過要放不同的圖片,圖片可能也之後不會使用官方的(有時間的話想改成自己想要的),再加上我們後面需要綁定 click
事件,怎麼想都應該要分開,所以我就拆出來寫了。
gallery
:四個圖片外的主要框架。pic
:四個區塊的基礎設定,包含滑鼠指上...等,都會做在這裡。img
:放入要顯示的照片。剛做好的時候長這樣:
$primary: #EC6565;
.frame {
color: #fff;
}
首先,就先把第一天教的小工具拿出來吸色,先把那個主要的紅色制作成變數 $primary
,後面一定很多地方會用到他。
再來就是到 .frame
把文字顏色直接改白色。
.gallery {
display: grid;
width: 100%;
height: 100%;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 4px;
padding: 4px;
overflow: hidden;
}
我將 gallery
設定為 grid layout,並做了以下設定:
grid-template-columns: 1fr 1fr
和 grid-template-rows: 1fr 1fr
將 gallery 分成四個均等的區塊,每行 2 個 column,並且總算有 2 行。gap: 4px
:設定了圖片之間的間距。padding: 4px
:為 gallery 外邊設置了內邊距。overflow: hidden
:確保任何超出範圍的內容會被隱藏。.gallery {
...
.pic {
cursor: pointer;
position: relative;
img {
width: 100%;
height: 100%;
}
}
}
這段很簡單的先設定 4 個 pic
的基本架構:
cursor: pointer
: 滑鼠移動到 .pic
上時,游標會變成手指。position: relative
: 將 .pic
定義為相對定位,這樣等等裡面的東西(像是壓黑跟[+]的按鈕才能定位在格子的中間。img
的部分,直接設定最大的寬高,讓它這樣才不會跟邊界之間有奇怪的空隙唷。
.gallery {
...
.pic {
...
&:before {
content: '';
background: #000;
opacity: 0;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
transition: all .6s ease-in-out;
}
&:hover:before {
opacity: 0.4;
}
}
}
&:before { ... }
content: ''
: 定義了 :before
的內容,即一個空的元素。background: #000
: 設置背景為黑色,制作我們的壓黑。opacity: 0
: 初始設置透明度為 0,表示 :before
的元素在未懸停時是隱藏的。position: absolute
: 絕對定位,使 :before
元素在 .pic
內自由定位。left: 0
right: 0
top: 0
bottom: 0
: 這些屬性將 :before
完全覆蓋 .pic
,延展到四個邊界,做出在格子內滿版的效果。transition: all .6s ease-in-out
: 定義了所有屬性變化的動畫效果,過渡時間是 0.6 秒,並使用平滑的進出效果。&:hover:before { ... }
opacity: 0.4
使得 :before
的透明度變為 0.4,從而顯示出來我們想要的淡淡的壓黑樣式,並與上面設置的 transition
效果一起提供平滑的漸變。$plusIconWH: 50px;
這邊我先制作這個 plus icon 的寬高,把它設定在變數內,接著我們就來制作 icon 本人。
.pic {
&:after {
content: '+';
position: absolute;
left: 50%;
top: 50%;
translate: -50% -50%;
background: $primary;
width: $plusIconWH;
height: $plusIconWH;
border-radius: 50%;
font-size: 30px;
line-height: .8;
font-weight: 400;
display: inline-flex;
justify-content: center;
align-items: center;
opacity: 0;
transition: all .4s ease-in-out;
transform: scale(2);
}
&:hover:after {
opacity: 1;
transform: scale(1) translate3d(0,0,0);
}
}
我使用 &:after
來制作它,.pic:after
是一個偽元素,主要用來創建一個在原始 HTML 結構中不存在的元素。
這裡的 :after
會在每個 .pic
元素之前插入一個加號(+)。具體作法如下:
content: '+'
:在圖片上方產生一個 "+" 的符號。position: absolute
left: 50%
top: 50%
translate: -50% -50%
:使用絕對定位,將偽元素的起點放在 .pic
的中心點,並通過 translate(-50%, -50%)
完全置中。background: $primary
:設置背景色。font-size: 30px
line-height: .8
font-weight: 400
:調整 "+" 符號的文字大小,讓它儘量貼近題目的樣式。width
和 height
:設定 "+" 背景的寬高,並將其設為圓形 (使用 border-radius: 50%
)。display: inline-flex
justify-content: center
align-items: center
:將 + 符號在偽元素內居中顯示,這裡一定要修改 display
也是因為偽元素一定要是區塊性質才能設定這些寬高,而我使用 inline-flex
是為了達到讓裡面的 "+" 符號居中。opacity: 0
和 transform: scale(2)
:初始狀態下 "+" 是透明且放大兩倍的。transition: all .4s ease-in-out
:定義了過渡效果,在狀態變更時平滑過渡。&:hover{
&:before {...}
&:after {
opacity: 1;
transform: scale(1) translate3d(0,0,0);
}
}
最後當然是把 hover
狀態內的 before
& after
整合在一起,在 after
的地方修改成我們滑鼠指上後要的透明度跟放大倍率,這樣就做好了。
由於篇幅太長了,我決定分兩篇寫,下一篇再來寫後面的 Info 頁面。
希望改變了這種按照步驟的寫法,能讓更多人看得懂,也能跟我一樣喜歡上寫CSS。
那今天就先到這裡,明天我們再繼續來玩下一集。